#pragma once

#include <iostream>
#include <string>
#include <vector>
#include <sstream>

using namespace std;

const string HttpSep = "\r\n";
const string homepage = "index.html";
const string wwwroot = "./wwwroot";

class HttpRequest
{
public:
    HttpRequest()
        : _req_blank(HttpSep), _path(wwwroot)
    {
    }
    ~HttpRequest() {}

    bool GetLine(string &str, string *line)
    {
        auto pos = str.find(HttpSep);
        if (pos == std::string::npos)
            return false;
        *line = str.substr(0, pos);
        str.erase(0, pos + HttpSep.size()); // 移除第一行，便于下次查找
        return true;
    }
    bool Deserialize(string &request)
    {
        string line;
        bool ok = GetLine(request, &line);
        if (!ok)
            return false;
        _req_line = line; // 请求行
        while (1)
        {
            bool ok = GetLine(request, &line);
            if (ok && line.empty())
            {
                // 说明读到了空行
                _req_content = request; // 剩下的就是内容
                break;
            }
            else if (ok && !line.empty())
            {
                _req_header.push_back(line);
            }
            else
            {
                break;
            }
        }
        return true;
    }

    void DebugHttp()
    {
        cout << "_req_line: " << _req_line << endl;
        for (auto &line : _req_header)
        {
            cout << "--->" << line << endl;
        }
        cout << "_req_blank: " << _req_blank << endl;
        cout << "_req_content: " << _req_content << endl;

        cout << "Method: " << _method << endl;
        cout << "url: " << _url << endl;
        cout << "http_version: " << _http_version << endl;
    }
    void ParseReqLine()
    {
        stringstream ss(_req_line);
        ss >> _method >> _url >> _http_version;
        if (_url == "/")
        {
            _path += _url;
            _path += homepage;
        }
        else
        {
            _path += _url;
        }
    }
    void ParseSuffix()
    {
        auto pos = _path.rfind(".");
        if (pos == std::string::npos)
        {
            _suffix = ".html";
        }
        else
            _suffix = _path.substr(pos);
    }

    void Parse()
    {
        // 1. 分析请求行
        ParseReqLine();
        // 2. 提取后缀
        ParseSuffix();
    }
    string Url()
    {
        return _url;
    }
    string Path()
    {
        return _path;
    }
    string Suffix()
    {
        return _suffix;
    }
    string GetFileContentHelper(const string& path)
    {
        std::ifstream in(path, std::ios::binary);
        if (!in.is_open())
            return "";
        std::ostringstream ss;
        ss << in.rdbuf();
        in.close();
        string content = ss.str();
        return content;
    }
    string GetFileContent()
    {
        return GetFileContentHelper(_path);
    }

    string Get_404()
    {
        return GetFileContentHelper("./wwwroot/404.html");
    }

private:
    // 报头字段
    string _req_line;
    vector<string> _req_header;
    string _req_blank;
    string _req_content;

    // 解析之后的内容
    string _method;
    string _url;
    string _http_version;

    string _path;

    string _suffix; // 请求资源的后缀
};

const string BlankSep = " ";
const string LineSep = "\r\n";

class HttpResponse
{
public:
    HttpResponse()
        : _http_version("HTTP/1.0"), _status_code(200), _status_code_desc("OK")
    {
    }
    ~HttpResponse() {}
    void SetCode(int code)
    {
        _status_code = code;
    }
    void SetDesc(const string &desc)
    {
        _status_code_desc = desc;
    }
    void MakeStatusLine()
    {
        _status_line = _http_version + BlankSep + std::to_string(_status_code) + BlankSep + _status_code_desc + LineSep;
    }
    void AddHeader(const string &header)
    {
        _resp_header.push_back(header);
    }

    void AddContent(const string &content)
    {
        _resp_content = content;
    }

    string Serialize()
    {
        string response_str = _status_line;
        for (auto &header : _resp_header)
        {
            response_str += header;
        }
        response_str += _resp_blank;
        response_str += _resp_content;
        return response_str;
    }

private:
    string _status_line;         // 状态行
    vector<string> _resp_header; // 响应报头
    string _resp_blank;
    string _resp_content; // body

    // httpversion StatusCode StatusCodeDesc
    string _http_version;
    int _status_code;
    string _status_code_desc;
};